package com.fingard.dsp.bank.directbank.srb01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.text.MFSHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.SmbFileUtil;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import org.apache.commons.lang.StringUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.fingard.text.StringHelper.trimEndFileSp;

public class SRB01BatPayRec extends SRB01Base implements IBatPayRec {
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {

        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        try {
            SRB01Header bankHeader = new SRB01Header();
            bankHeader.trCode = "300002";
            bankHeader.reqSeqNo = p_req1988.reqBatchNO;

            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.autoFormat = false;
            writeCommonHeader(xmlWriter, bankHeader, true);
            XElement tmpXElement = new XElement("body", "");
            tmpXElement.addChild(new XElement("pay_acno", p_req1988.ownAct));               //付款账号
            tmpXElement.addChild(new XElement("pay_cur_code"
                    , convertCurToBank(p_req1988.ownCur)));                                         //付款币种
            tmpXElement.addChild(new XElement("pay_acname", p_req1988.ownActName));         //付款户名
            tmpXElement.addChild(new XElement("pay_accaddr", ""));              //付款地址
            tmpXElement.addChild(new XElement("as_flag", "0"));                 //是否使用账簿号 0：不需要 1：需要
            tmpXElement.addChild(new XElement("as_acno", ""));                  //账簿号
            tmpXElement.addChild(new XElement("as_acname", ""));                //账簿名称
            tmpXElement.addChild(new XElement("vir_acno", ""));                 //虚账号
            tmpXElement.addChild(new XElement("vir_acname", ""));               //虚账号名称
            tmpXElement.addChild(new XElement("supply_item",
                    p_req1988.useType.contains("工资") ? "0001" : "0002"));                          //付款类型 0001-代发工资 0002-费用报销
            tmpXElement.addChild(new XElement("batch_no", p_req1988.reqBatchNO));           //批次号
            tmpXElement.addChild(new XElement("count", p_req1988.totalNum));                //总笔数
            tmpXElement.addChild(new XElement("amt", p_req1988.totalAmt));                  //总金额
            tmpXElement.addChild(new XElement("purpose", p_req1988.useType));               //用途
            tmpXElement.addChild(new XElement("postscript", ""));               //附言
            tmpXElement.addChild(new XElement("qry_auth", ""));                 //查看权限操作员
            String fileName = Format.Date8Format.format(new Date()) + p_req1988.reqBatchNO
                    + "bat.dat";                                                                    //日期(yyyyMMdd)+批次号+bat.dat
            tmpXElement.addChild(new XElement("file_name", fileName));                      //文件名
            tmpXElement.addChild(new XElement("field_num", "6"));
            tmpXElement.addChild(new XElement("record_num", p_req1988.totalNum));
            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndElement();  //ap
            xmlWriter.writeEndDocument();
            StringBuilder sb = new StringBuilder();
            String newLine = "\n";
            sb.append("acno|cur_code|acname|cardflag|amt|postscript|").append(newLine);
            String separator = "|";
            while (p_req1988.readRecord()) {
                ReqPayRecDetail detail = p_req1988.readedDetail;
                String postscript = detail.useType + "＋" + detail.askNumber;
                sb.append(detail.recAct).append(separator)
                        .append(convertCurToBank(detail.payCur)).append(separator)
                        .append(detail.recName).append(separator)
                        .append("1".equals(detail.cardType) ? "1" : "0").append(separator)   // 1:折 0:卡
                        .append(detail.payAmount).append(separator)
                        .append(postscript).append(separator).append(newLine);
            }
            //共享目录方式
            if (StringHelper.hasAnyChar(bankFront.bkTransFolder)) {
                if (bankFront.bkTransFolder.startsWith("smb://")) {
                    StringBuilder smbSb = new StringBuilder();
                    int result = SmbFileUtil.smbWrite(bankFront.bkTransFolder + "/" + fileName, sb.toString(), getCharset(), smbSb);
                    if (result < 0) {
                        WriteBankLogLn("写入共享目录出错，出错原因为：" + smbSb.toString());
                        throw new Exception(smbSb.toString());
                    }
                } else {
                    //上传文件名，来盘文件名规则：自然日期（YYYYMMDD，共8位）+ 批次号.dat
                    String uploadFilePath = StringHelper.trimEnd(bankFront.bkTransFolder, File.separator)
                            + File.separator + fileName;
                    FileHelper.writeFile(uploadFilePath, sb.toString(), getCharset());
                    WriteBankLogLn2("批次号映射文件路径: " + uploadFilePath);
                }
            } else {
                throw new Exception("请配置银行前置机目录");
            }
            //region 发送请求报文，并获取响应报文
            String[] retStrArr = sendToBank(xmlWriter.toXmlString());
            if (retStrArr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    retAts.respCode = "0";
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/head/ret_code");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/head/ext_info");
                    String succFlag = tmpBkReader.getFirstText("/ap/head/succ_flag");
                    retAts.transState = succFlag + "+" + tmpRetCode;
                    retAts.payInfoCode = retAts.transState;
                    retAts.respInfo = StringUtils.isEmpty(tmpRetInfo) ? tmpBkReader.getFirstText("/ap/head/ret_info") : tmpRetInfo;
                    retAts.reqSeqID = tmpBkReader.getFirstText("/ap/head/req_no");
                    retAts.writeRetToATS();
                    return retAts;
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = (tmpSbMsg.toString());
                    retAts.writeRetToATS();
                    return retAts;
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = retStrArr[1];
                retAts.writeRetToATS();
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
        }
        return retAts;
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        try {
            retAts.reqSeqID = p_req1998.reqBatchNO;
            SRB01Header bankHeader = new SRB01Header();
            bankHeader.trCode = "200100";
            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.autoFormat = false;
            writeCommonHeader(xmlWriter, bankHeader, false);
            XElement tmpXElement = new XElement("body", "");
            tmpXElement.addChild(new XElement("start_date", Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1998.bgnDate)))); //开始时间
            tmpXElement.addChild(new XElement("end_date", Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1998.bgnDate))));   //结束时间
            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndElement();  //ap
            xmlWriter.writeEndDocument();
            //region 发送请求报文，并获取响应报文
            String[] retStrArr = sendToBank(xmlWriter.toXmlString());
            Map<String, String> parseResultMap = parseRespMsg(retStrArr, p_req1998.reqBatchNO, retAts);
            if (parseResultMap.get("reqBatchNo") != null) {
                getBatchResultDetail(p_req1998, retAts, parseResultMap.get("serialNo"));
            } else {
                retAts.respCode = "0";
                retAts.respInfo = "无该批次信息，请确认批次号是否正确！";
                retAts.transState = "0+无该批次信息，请确认批次号是否正确";
                retAts.payInfoCode = "0+无该批次信息，请确认批次号是否正确";
            }

        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            e.printStackTrace();
        }
        retAts.writeAfterDetail();
        return retAts;
    }

    private void getBatchResultDetail(ReqQryBatPayRec p_req1998, RetAtsQryBatPayRec retAts, String serialNo) {
        try {
            SRB01Header bankHeader = new SRB01Header();
            bankHeader.trCode = "200201";
            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.autoFormat = false;
            writeCommonHeader(xmlWriter, bankHeader, false);
            XElement tmpXElement = new XElement("body", "");
            tmpXElement.addChild(new XElement("tr_acdt", Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1998.bgnDate))));   //开始时间
            tmpXElement.addChild(new XElement("serial_no", serialNo));                                                                  //流水号
            tmpXElement.addChild(new XElement("batch_no", p_req1998.reqBatchNO));                                                       //批次号
            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndElement();  //ap
            xmlWriter.writeEndDocument();
            //region 发送请求报文，并获取响应报文
            String[] retStrArr = sendToBank(xmlWriter.toXmlString());
//            String[] retStrArr = new String[]{"", "<ap><head><tr_code>200201</tr_code><cms_corp_no></cms_corp_no><user_no></user_no><req_no></req_no><serial_no>13307032</serial_no><tr_acdt>20200323</tr_acdt><tr_time>141608</tr_time><succ_flag>3</succ_flag><ret_info>批次状态正在处理</ret_info><ret_code>3303</ret_code><ext_info>批次正在处理，请稍后查询明细</ext_info><reserved></reserved><file_flag></file_flag><org_code></org_code></head></ap>"};
            Map<String, String> resultMap = new HashMap();
            String tmpRespCode = "";
            String tmpRespInfo = "";
            if (retStrArr[0].length() == 0) {
                StringBuilder curSbMsg = new StringBuilder();
                XmlTextReader curBkReader = loadBankRespXmlReader(retStrArr[1], curSbMsg);
                if (curBkReader != null) {
                    String curRetCode = curBkReader.getFirstText("/ap/head/ret_code");
                    String curRetInfo = curBkReader.getFirstText("/ap/head/ret_info");
                    String curDataMFS = "";
                    if ("0000".equals(curRetCode)) {
                        int curRecordNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/record_num"));
                        int curFieldNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/field_num"));
                        if (curRecordNum > 0) {
                            String curFileFlag = curBkReader.getFirstText("/ap/head/file_flag");
                            if ("1".equals(curFileFlag)) {
                                String curFileName = curBkReader.getFirstText("/ap/body/file_name");
                                //共享目录方式
                                if (StringHelper.hasAnyChar(bankFront.bkTransFolder)) {
                                    if (bankFront.bkTransFolder.startsWith("smb://")) {
                                        //下载共享目录批量查询文件
                                        String downloadFilePath = trimEndFileSp(bankFront.bkTransFolder) + File.separator;//共享目录路径
                                        String p_FileFullPath = getTempFileDirectory() + File.separator + Format.Time6Format.format(new Date());//下载到的本地路径
                                        StringBuilder p_sb = new StringBuilder();
                                        if (SmbFileUtil.smbDownload(p_FileFullPath, downloadFilePath, curFileName, p_sb) == 1) {
                                            p_FileFullPath = p_FileFullPath + File.separator + curFileName;
                                            WriteBankLogLn("文件下载成功，位于：" + p_FileFullPath);
                                            curDataMFS = FileHelper.readFileText(p_FileFullPath, getCharset());
                                        } else {
                                            retAts.writeRespCode("-1");
                                            retAts.writeRespInfo(p_sb.toString());
                                            retAts.writeEnd();
                                        }
                                    } else {
                                        String curFilePath = StringHelper.trimEnd(bankFront.bkTransFolder, File.separator) + File.separator + curFileName;
                                        WriteBankLogLn("读取前置数据文件：" + curFilePath);
                                        curDataMFS = FileHelper.readFileText(curFilePath, getCharset());
                                        WriteBankLogStep3(curDataMFS);
                                    }
                                } else {
                                    throw new Exception("请配置银行前置机回单目录");
                                }
                            } else {
                                curDataMFS = curBkReader.getFirstText("/ap/body/serial_record");
                            }
                            if (curDataMFS != null) {
                                retAts.respCode = "0";
                                retAts.reqSeqID = p_req1998.reqBatchNO;
                                StringBuilder curSbLog = new StringBuilder();
                                ArrayList<String[]> curDataList = MFSHelper.getTextArray(curDataMFS, "|", curFieldNum, curRecordNum + 1, curSbLog);
                                if (curSbLog.length() == 0) {
                                    //region **字段映射表
                                        /*
                                         [0]交易序号(C30)|  [1]账号(C35)|     [2]币种(C2)|          [3]户名(C140)|
                                         [4]借贷标志(C1)|   [5]金额(N15,2)|   [6]摘要(C60)|         [7]交易日期(C8)|
                                         [8]交易时间(C6)|   [9]交易状态(C1)|   [10]错误信息(60)|     [11]批次号(C20)|
                                         */
                                    //endregion
                                    for (int i = 1; i < curDataList.size(); i++) {
                                        String[] curRowDataArr = curDataList.get(i);
                                        RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                        tmpRetDetail.recAct = curRowDataArr[1].trim();
                                        tmpRetDetail.recName = curRowDataArr[3].trim();
                                        String purpose = curRowDataArr[6].trim();
                                        if (purpose.contains("＋")) {
                                            tmpRetDetail.postScript = purpose.substring(purpose.lastIndexOf("＋") + 1, purpose.length());
                                            tmpRetDetail.usage = purpose.substring(0, purpose.lastIndexOf("＋"));
                                        } else {
                                            tmpRetDetail.postScript = "";
                                            tmpRetDetail.usage = curRowDataArr[6];
                                        }
                                        tmpRetDetail.payAmount = curRowDataArr[5].trim();
                                        tmpRetDetail.result = curRetCode + "+" + curRowDataArr[9].trim();
                                        tmpRetDetail.payInfoCode = tmpRetDetail.result;
                                        tmpRetDetail.memo = curRowDataArr[10].trim();
                                        retAts.writeRetDetail(tmpRetDetail);
                                    }
                                } else {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = curSbLog.toString();
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = "数据为空";
                            }
                        }
                    } else if ("3303".equals(curRetCode)){
                        retAts.respCode = "0";
                        retAts.respInfo = curRetInfo;
                        retAts.transState = "0000+8";
                        retAts.payInfoCode = "0000+8";
                    } else {

                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = curSbMsg.toString();
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = retStrArr[1];
            }

        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            e.printStackTrace();
        }

    }

    //解析响应报文
    private Map<String, String> parseRespMsg(String[] retStrArr, String batchNo, RetAtsQryBatPayRec retAts) throws Exception {
        Map<String, String> resultMap = new HashMap();
        String tmpRespCode = "";
        String tmpRespInfo = "";
        if (retStrArr[0].length() == 0) {
            StringBuilder curSbMsg = new StringBuilder();
            XmlTextReader curBkReader = loadBankRespXmlReader(retStrArr[1], curSbMsg);
            if (curBkReader != null) {
                String curRetCode = curBkReader.getFirstText("/ap/head/ret_code");
                String curRetInfo = curBkReader.getFirstText("/ap/head/ret_info");
                String curDataMFS = "";
                if ("0000".equals(curRetCode)) {
                    int curRecordNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/record_num"));
                    int curFieldNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/field_num"));
                    if (curRecordNum > 0) {
                        String curFileFlag = curBkReader.getFirstText("/ap/head/file_flag");
                        String curFileName = curBkReader.getFirstText("/ap/body/file_name");
                        if ("1".equals(curFileFlag)) {
                            //共享目录方式
                            if (StringHelper.hasAnyChar(bankFront.bkTransFolder)) {
                                if (bankFront.bkTransFolder.startsWith("smb://")) {
                                    //下载共享目录批量查询文件
                                    String downloadFilePath = trimEndFileSp(bankFront.bkTransFolder) + File.separator;//共享目录路径
                                    String p_FileFullPath = getTempFileDirectory() + File.separator + Format.Time6Format.format(new Date());//下载到的本地路径
                                    StringBuilder p_sb = new StringBuilder();
                                    if (SmbFileUtil.smbDownload(p_FileFullPath, downloadFilePath, curFileName, p_sb) == 1) {
                                        p_FileFullPath = p_FileFullPath + File.separator + curFileName;
                                        WriteBankLogLn("文件下载成功，位于：" + p_FileFullPath);
                                        curDataMFS = FileHelper.readFileText(p_FileFullPath, getCharset());
                                    } else {
                                        retAts.writeRespCode("-1");
                                        retAts.writeRespInfo(p_sb.toString());
                                        retAts.writeEnd();
                                    }
                                } else {
                                    String curFilePath = StringHelper.trimEnd(bankFront.bkTransFolder, File.separator) + File.separator + curFileName;
                                    WriteBankLogLn("读取前置数据文件：" + curFilePath);
                                    curDataMFS = FileHelper.readFileText(curFilePath, getCharset());
                                    WriteBankLogStep3(curDataMFS);
                                }
                            } else {
                                throw new Exception("请配置银行前置机回单目录");
                            }
                        } else {
                            curDataMFS = curBkReader.getFirstText("/ap/body/serial_record");
                        }
                        if (curDataMFS != null) {
                            StringBuilder curSbLog = new StringBuilder();
                            ArrayList<String[]> curDataList = MFSHelper.getTextArray(curDataMFS, "|", curFieldNum, curRecordNum + 1, curSbLog);
                            if (curSbLog.length() == 0) {
                                //region **字段映射表
                                        /*
                                         [0]流水号(C20)|           [1]批次号(C20)|    [2]账号(C35)|
                                         [3]币种(C2)|             [4]户名(140)|     [5]付款类型(C4)|
                                         [6]付款类型名称(C60)|     [7]总笔数(Int)|    [8]总金额(N15,2)|
                                         [9]成功笔数(Int)|        [10]成功金额(N15,2)|    [11]交易日期(C8)|
                                         [12]交易时间(C6)|        [13]交易状态(C1)|       [14]客户号(C20)|
                                         [15]客户名称(C140)|      [16]用户号(C10)|   [17]用户名(C60)|
                                         [18]摘要(C60)|           [19]核心批次号(C60)| [20]用途(C60)|
                                         [21]附言(C300)|          [22]查看权限操作员(C300)|  [23]账簿号(C38)|
                                         [24]账簿名称(C140)|       [25]企业批次号|
                                         */
                                //endregion
                                for (int i = 1; i < curDataList.size(); i++) {
                                    String[] curRowDataArr = curDataList.get(i);
                                    if (batchNo.equals(curRowDataArr[25].trim())) {
                                        resultMap.put("serialNo", curRowDataArr[0].trim());
                                        resultMap.put("reqBatchNo", curRowDataArr[25].trim());
                                    }
                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = curSbLog.toString();
                            }
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = "数据为空";
                        }
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = curRetInfo;
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = curSbMsg.toString();
            }
        } else {
            tmpRespCode = "-1";
            tmpRespInfo = retStrArr[1];
        }
        resultMap.put("tmpRespCode", tmpRespCode);
        resultMap.put("tmpRespInfo", tmpRespInfo);
        return resultMap;
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return null;
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return null;
    }
}
